import lombok.ToString;

/**
 * @author zxs
 * @since 2020/05/14
 */
@ToString
public abstract class Pizza {

    private String a;
    private String b;

    abstract static class Builder<T extends Builder<T>>{
        private String a;
        private String b;

        public T a(String var){
            a=var;
            return self();
        }

        public T b(String var){
            b=var;
            return self();
        }

        abstract Pizza build();

        protected abstract T self();
    }

    Pizza(Builder<?> builder){
        this.a=builder.a;
        this.b=builder.b;
    }
}

@ToString
class PizzaA extends Pizza{

    private String c;

    public static class Builder extends Pizza.Builder<Builder>{

        private String c;

        public Builder c(String var){
            this.c=var;
            return self();
        }

        @Override
        Pizza build() {
            return new PizzaA(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }

    PizzaA(Builder builder){
        super(builder);
        this.c = builder.c;
    }

    static Builder builder() {
        return new PizzaA.Builder();
    }
}

@ToString
class PizzaB extends Pizza{

    private String d;

    public static class Builder extends Pizza.Builder<Builder>{

        private String d;

        public Builder d(String var){
            this.d=var;
            return self();
        }

        @Override
        Pizza build() {
            return new PizzaB(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }

    PizzaB(Builder builder){
        super(builder);
        this.d = builder.d;
    }

    static Builder builder() {
        return new PizzaB.Builder();
    }
}
